namespace taurus.client {

    /**
     * TObject entity
     */
    export class TObject implements ITObject {
        private dataHolder: any;

        public static newInstance(): ITObject {
            return new TObject();
        }

        public static  newFromBinaryData(bytes: ByteArray) :ITObject{
            return TDataSerializer.me().binary2object(bytes);
        }

        public static  newFromJson(json: string) :ITObject{
            return TDataSerializer.me().json2object(json);
        }
        
        public constructor() {
            this.dataHolder = {};
        }

        containsKey(key: string): boolean {
            if (this.dataHolder[key]) return true;
            return false;
        }

        getBool(key: string): boolean {
            var o = <TDataWrapper>this.dataHolder[key];
            if (o == null) return null;
            return o.data;
        }

        getByte(key: string): number {
            var o = <TDataWrapper>this.dataHolder[key];
            if (o == null) return null;
            return o.data;
        }

        getByteArray(key: string): Uint8Array {
            var o = <TDataWrapper>this.dataHolder[key];
            if (o == null) return null;
            return o.data;
        }

        get(key: string): TDataWrapper {
            return this.dataHolder[key];
        }

        getDouble(key: string): number {
            var o = <TDataWrapper>this.dataHolder[key];
            if (o == null) return null;
            return o.data;
        }

        getFloat(key: string): number {
            var o = <TDataWrapper>this.dataHolder[key];
            if (o == null) return null;
            return o.data;
        }

        getInt(key: string): number {
            var o = <TDataWrapper>this.dataHolder[key];
            if (o == null) return null;
            return o.data;
        }

        getKeys(): string[] {
            return Object.keys(this.dataHolder);
        }

        getLong(key: string): number {
            var o = <TDataWrapper>this.dataHolder[key];
            if (o == null) return null;
            return o.data;
        }

        getTArray(key: string): ITArray {
            var o = <TDataWrapper>this.dataHolder[key];
            if (o == null) return null;
            return o.data;
        }

        getTObject(key: string): ITObject {
            var o = <TDataWrapper>this.dataHolder[key];
            if (o == null) return null;
            return o.data;
        }

        getShort(key: string): number {
            var o = <TDataWrapper>this.dataHolder[key];
            if (o == null) return null;
            return o.data;
        }

        getString(key: string): string {
            var o = <TDataWrapper>this.dataHolder[key];
            if (o == null) return null;
            return o.data;
        }

        isNull(key: string): boolean {
            var o = <TDataWrapper>this.dataHolder[key];
            if (o == null) return false;
            return o.type == TDataType.NULL;
        }

        put(key: string, val: TDataWrapper) {
            this.putObj(key, val, null);
        }

        private putObj(key: string, value: any, typeId: TDataType) {
            if (key == null) {
                throw "TObject requires a non-null key for a 'put' operation!";
            }
            if (key.length > 255) {
                throw "TObject keys must be less than 255 characters!";
            }
            if (value == null) {
                throw "TObject requires a non-null value! If you need to add a null use the putNull() method.";
            }
            if (value instanceof TDataWrapper)
                this.dataHolder[key] = value;
            else
                this.dataHolder[key] = new TDataWrapper(typeId, value);
        }

        putBool(key: string, val: boolean) {
            this.putObj(key, val, TDataType.BOOL);
        }

        putByte(key: string, val: number) {
            this.putObj(key, val, TDataType.BYTE);
        }

        putByteArray(key: string, val: Uint8Array) {
            this.putObj(key, val, TDataType.BYTE_ARRAY);
        }

        putDouble(key: string, val: number) {
            this.putObj(key, val, TDataType.DOUBLE);
        }

        putFloat(key: string, val: number) {
            this.putObj(key, val, TDataType.FLOAT);
        }

        putInt(key: string, val: number) {
            this.putObj(key, val, TDataType.INT);
        }

        putLong(key: string, val: number) {
            this.putObj(key, val, TDataType.LONG);
        }
        putNull(key: string) {
            this.dataHolder.put(key, new TDataWrapper(TDataType.NULL, null));
        }

        putTArray(key: string, val: ITArray) {
            this.putObj(key, val, TDataType.TARRAY);
        }

        putTObject(key: string, val: ITObject) {
            this.putObj(key, val, TDataType.TOBJECT);
        }

        putShort(key: string, val: number) {
            this.putObj(key, val, TDataType.SHORT);
        }

        putString(key: string, val: string) {
            this.putObj(key, val, TDataType.STRING);
        }

        del(key: string) {
            delete this.dataHolder[key];
        }

        size(): number {
            return Object.keys(this.dataHolder).length;
        }

        toBinary(): ByteArray {
            return TDataSerializer.me().object2binary(this);
        }

        toJson():string{
            return TDataSerializer.me().object2json(this);
        }

    }

    /**
     * 
     */
    export class TObjectLite extends TObject {
        
        public constructor(){
            super();
        }
        
        public getByte(key:string):number {
            var d = super.getDouble(key);
            return d;
        }
        
        public getShort(key:string):number {
            var d = super.getDouble(key);
            return d;
        }
        
        public getFloat(key:string):number {
            var d = super.getDouble(key);
            return d;
        }

        public getLong(key:string):number {
            var d = super.getDouble(key);
            return d;
        }

        public getInt(key:string):number {
            var d = super.getDouble(key);
            return d;
        }
    }
}